package com.sf.dlb.web.service;

import com.sf.dlb.bean.ETHWalletRequestBean;
import com.sf.dlb.bean.ETHWalletResponseBean;
import com.sf.dlb.constant.ResponseConstant;
import com.sf.dlb.jpa.model.WalletExtractInfo;
import com.sf.dlb.jpa.repository.WalletExtractRepository;
import com.sf.dlb.utils.GsonUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * 后台子线程
 * Created by tanjing on 2019/3/12.
 */
@Service
public class BackThreadService implements InitializingBean,DisposableBean,Runnable{
    private Logger logger= LoggerFactory.getLogger(BackThreadService.class);
    private Thread thread;
    private volatile boolean someCondition=true;
    public LinkedBlockingQueue<ETHWalletRequestBean> queueConsumer=new LinkedBlockingQueue<>();
    public ArrayList<ETHWalletRequestBean> queueConsumerList=new ArrayList<>();//用于存储队列中有哪些任务

    @Autowired
    private WalletExtractRepository walletExtractRepository;
    @Autowired
    private ETHWalletService userETHWalletService;
    @Resource
    private ExecutorService executorService;


    @Override
    public void run() {
        logger.info("BackThreadService run ");
        while (someCondition){
            handlerExtractQueue();
        }
    }

    @Override
    public void destroy() {
        logger.info("BackThreadService destroy ");
        someCondition=false;
        if(null!=executorService&&!executorService.isShutdown()) {
            logger.info("== BackThreadService executorService.shutdown()");
            executorService.shutdown();
        }
    }

    public void handlerExtractQueue(){
        logger.info("== BackThreadService handlerExtractQueue");
        try {
            boolean nextTast=true;
            int sleepCount=0;
            do {
                //发送之前，先验证一下，上一个超时的记录是否打包成功
                WalletExtractInfo walletExtractInfo = walletExtractRepository.quereyOneExxtractSuccess();
                if(null==walletExtractInfo){
                    //如果都成功；或者第一次就为空
                    logger.info("== handlerExtractQueue null==walletExtractInfo ");
                    break;
                }
                String userId = walletExtractInfo.getUserId();
                List<String> strings = new ArrayList<>();
                strings.add(walletExtractInfo.getTxNumber());
                List list=userETHWalletService.extractRecrd(userId, strings);
                if(list.size()>0){
                    logger.info("== Thread.sleep list.size()>0 userId={}",userId);
                    //打包成功，继续下一个任务
                    walletExtractInfo.setExtractState(ResponseConstant.extract_state_complete);
                    walletExtractInfo.setUpdateDate(new Date());
                    walletExtractRepository.save(walletExtractInfo);
                    nextTast=false;
                }else{
                    //打包失败，继续等待，自旋等待
                    Thread.sleep(5000L);
                    sleepCount++;
                    logger.info("== Thread.sleep sleepCount={},userId={}",sleepCount,userId);
                }
            }while (nextTast);
            //从队列取出任务,从集合中移除任务
            ETHWalletRequestBean ethWalletRequestBean=queueConsumer.take();
            queueConsumerList.remove(ethWalletRequestBean);
            logger.info("== handlerExtractQueue ethWalletRequestBean={},queueConsumerList={}",GsonUtils.getInstance().toJson(ethWalletRequestBean),queueConsumerList.size());
            ETHWalletResponseBean ethWalletResponseBean=userETHWalletService.extractETH(ethWalletRequestBean);
            if(null==ethWalletResponseBean){
                logger.info("== handlerExtractQueue ethWalletResponseBean == null 提现失败 ");
                return;
            }
            String ExtractState= ResponseConstant.extract_state_complete;
            String responseCode=ethWalletResponseBean.getResponseCode();
            if(StringUtils.isNotBlank(responseCode)&&responseCode.equals("504")){
                ExtractState=ResponseConstant.extract_state_unfinished;
            }
            //更新hash码
            String extractNmber=ethWalletResponseBean.getExtractNumber();
            String txNumber=ethWalletResponseBean.getTransactionHash();
            WalletExtractInfo walletExtractInfo = walletExtractRepository.findByExtractNumberAndDelFlag(extractNmber,"0");
            walletExtractInfo.setTxNumber(txNumber);
            walletExtractInfo.setExtractState(ExtractState);
            walletExtractInfo.setUpdateDate(new Date());
            walletExtractRepository.save(walletExtractInfo);
        } catch (InterruptedException e) {
            e.printStackTrace();
            logger.info("== handlerExtractQueue errer InterruptedException");
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        logger.info("BackThreadService afterPropertiesSet ");
        this.thread=new Thread(this);
        this.thread.start();
    }
}
